package com.blog.itpub;

import org.apache.commons.lang3.tuple.Pair;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

public final class SimpleCrawler {

	private SimpleCrawler(){}

	public static Pair<Integer,String> get(String url,Charset charset) throws IOException {
		URL fetchUrl = toUrl(url);
		HttpURLConnection conn = (HttpURLConnection)fetchUrl.openConnection();

		conn.setRequestProperty("Content-Type", "text/html; charset=" + charset.displayName());
		conn.setReadTimeout(3000);
		conn.setConnectTimeout(3000);

		int code = conn.getResponseCode();
		Map<String,List<String>> heads = conn.getHeaderFields();
		if( heads != null ){
		String c = getCharset(heads);
		if( !charset.displayName().equalsIgnoreCase(c) && c != null ){
			System.out.println(String.format("[warn]configed charset is %s,but Content-Type is %s",charset.displayName(),c));
			charset = Charset.forName(c);
		}
		}

		StringBuffer content = new StringBuffer();
		if( code == 200 ){
			char[] buf = new char[512];
			int readLen;
			InputStreamReader reader = new InputStreamReader(conn.getInputStream(),charset);

			while( (readLen = reader.read(buf,0,512)) != -1 ){
				content.append(new String(buf,0,readLen));
			}
			reader.close();
		}

		return Pair.of(code,content.toString());
	}

	public static Pair<Integer,String> post(String url,String content,Charset charset) throws IOException {
		URL fetchUrl = toUrl(url);
		HttpURLConnection conn = (HttpURLConnection)fetchUrl.openConnection();

		conn.setDoInput(true);
		conn.setDoOutput(true);

		conn.setRequestMethod("POST");
		conn.setRequestProperty("Content-Type","plain/text; charset=" + charset.displayName());

		conn.getOutputStream().write(content.getBytes(charset));

		int code = conn.getResponseCode();
		StringBuffer buffer = new StringBuffer();
		if( code == 200 ){
			char[] buf = new char[512];
			int readLen;
			InputStreamReader reader = new InputStreamReader(conn.getInputStream(),charset);

			while( (readLen = reader.read(buf,0,512)) != -1 ){
				buffer.append(new String(buf,0,readLen));
			}
			reader.close();
		}

		return Pair.of(code,buffer.toString());
	}

	private static URL toUrl(String url) throws MalformedURLException {
		return new URL(url);
	}

	private static String getCharset(Map<String,List<String>> header){
		for( String key : header.keySet() ){
			if(key == null) continue;
			if( key.equalsIgnoreCase("Content-Type") ){
				List<String> subList = header.get(key);
				for( String val : subList ){
					val = val.toLowerCase();
					int pos = val.indexOf("charset=");
					if( pos >= 0 ){
						int pos2 =val.indexOf(";",pos);
						return val.substring(pos + "charset=".length(),(pos2 == -1) ? val.length() : pos2);
					}
				}
			}
		}
		return null;
	}

	public static void main(String[] args) throws IOException {
		//Map<String,List<String>> map = Maps.newHashMap();
		//map.put("Content-Type", Lists.asList("charset=UTF-8;",new String[]{""}));
		//System.out.println(getCharset(map));
		System.out.println(get("http://www.jd.com", Charset.forName("UTF-8")).getRight());
	}

}
